/**
 * @author YinHang
 */
;(function () {
	var Map = GameFramework.inherit("ui.g2d.Displayable")(function (image, mapArr, sWidth, sHeight, mWidth, mHeight) {
		if(!image.loaded)
			return null;
		this.mapSprite = new ui.g2d.Sprite(image, sWidth, sHeight);
		this.canvas = new ui.g2d.Canvas(document.createElement("canvas"), mWidth, mHeight);
		this.graphics = this.canvas.getGraphics();
		this.setMapArr(mapArr);
		Map.base.call(this, 0, 0, mWidth, mHeight, true);
	});
	
	var Prototype = Map.prototype;
	
	Prototype.setMapArr = function (mapArr) {
		this.mapArr = mapArr;
		this.initMapInfo();
	};
	
	Prototype.getMapSprite = function () {
		return this.mapSprite;
	};
	
	Prototype.getUpBlock = function (mapInfo) {
		return this.mapInfoArr[mapInfo.col - 1] ? this.mapInfoArr[mapInfo.col - 1][mapInfo.row] : null;
	};
	
	Prototype.getRightBlock = function (mapInfo) {
		return this.mapInfoArr[mapInfo.col] ? this.mapInfoArr[mapInfo.col][mapInfo.row + 1] : null;
	};
	
	Prototype.getDownBlock = function (mapInfo) {
		return this.mapInfoArr[mapInfo.col + 1] ? this.mapInfoArr[mapInfo.col + 1][mapInfo.row] : null;
	};
	
	Prototype.getLeftBlock = function (mapInfo) {
		return this.mapInfoArr[mapInfo.col] ? this.mapInfoArr[mapInfo.col][mapInfo.row - 1] : null;
	};
	
	Prototype.getMapArr = function () {
		return this.mapArr;
	};
	
	Prototype.getBlockWidth = function () {
		return this.mapSprite.getWidth();
	};
	
	Prototype.getBlockHeight = function () {
		return this.mapSprite.getHeight();
	};
	
	Prototype.setBlock = function (col, row, frame) {
		this.mapArr[col][row] = frame;
		this.setBlockInfo(col, row, "frame", frame);
	};
	
	Prototype.setBlockInfo = function (col, row, name, value) {
		this.mapInfoArr[col][row][name] = value;
	};
	
	Prototype.initMapInfo = function () {
		this.mapInfoArr = [];
		var host = this;
		var mapColSize = this.mapArr.length;
		for(var i=0;i<mapColSize;++i)
		{
			var mapRowSize = this.mapArr[i].length;
			for(var j=0;j<mapRowSize;++j)
			{
				if(!this.mapInfoArr[i])
					this.mapInfoArr[i] = [];
				this.mapInfoArr[i][j] = {
					frame: host.mapArr[i][j],
					x: host.mapSprite.getWidth() * j,
					y: host.mapSprite.getHeight() * i,
					col: i,
					row: j
				};
			}
		}
	};
	
	Prototype.setX = function (x) {
		this.$_setX(x);
		this.canvas.setX(x);
	};
	
	Prototype.getFirstBlock = function (frame) {
		var mapColSize = this.mapInfoArr.length;
		for(var i=0;i<mapColSize;++i)
		{
			var mapRowSize = this.mapInfoArr[i].length;
			for(var j=0;j<mapRowSize;++j)
			{
				if(this.mapInfoArr[i][j].frame == frame)
					return this.mapInfoArr[i][j];
			}
		}
	};
	
	Prototype.getLastBlock = function (frame) {
		for(var i=this.mapInfoArr.length - 1;i>=0;--i)
		{
			var mapRowSize = this.mapInfoArr[i].length;
			for(var j=this.mapInfoArr[i].length - 1;j>=0;--j)
			{
				if(this.mapInfoArr[i][j].frame == frame)
					return this.mapInfoArr[i][j];
			}
		}
	};
	
	Prototype.getBlocks = function (frame) {
		var mapColSize = this.mapInfoArr.length;
		var result = [];
		for(var i=0;i<mapColSize;++i)
		{
			var mapRowSize = this.mapInfoArr[i].length;
			for(var j=0;j<mapRowSize;++j)
			{
				if(this.mapInfoArr[i][j].frame == frame)
					result.push(this.mapInfoArr[i][j]);
			}
		}
		return result;
	};
	
	Prototype.setY = function (y) {
		this.$_setY(y);
		this.canvas.setY(y);
	};
	
	Prototype.setWidth = function (width) {
		this.$_setWidth(width);
		this.canvas.setWidth(width);
	};
	
	Prototype.setHeight = function (height) {
		this.$_setHeight(height);
		this.canvas.setHeight(height);
	};
	
	Prototype.blockCollisionWithRect = function (x, y, width, height) {
		var mapInfoColSize = this.mapInfoArr.length;
		var spriteWidth = this.mapSprite.getWidth();
		var spriteHeight = this.mapSprite.getHeight();
		var canvasX = this.canvas.getX();
		var canvasY = this.canvas.getY();
		for(var i=0;i<mapInfoColSize;++i)
		{
			var mapInfoRowSize = this.mapInfoArr[i].length;
			for(var j=0;j<mapInfoRowSize;++j)
			{
				var mapInfo = this.mapInfoArr[i][j];
				if(ui.g2d.physics.Physics.RectCollision(mapInfo.x + canvasX, mapInfo.y + canvasY, spriteWidth, spriteHeight, x, y, width, height))
					return mapInfo;
			}
		}
		return false;
	};
	
	Prototype.drawToBuffer = function () {
		var mapColSize = this.mapArr.length;
		for(var i=0;i<mapColSize;++i)
		{
			var mapRowSize = this.mapArr[i].length;
			for(var j=0;j<mapRowSize;++j)
			{
				if(this.mapArr[i][j] == 0)
					continue;
				var mapInfo = this.mapInfoArr[i][j];
				this.mapSprite.setFrame(mapInfo.frame);
				this.mapSprite.setX(mapInfo.x);
				this.mapSprite.setY(mapInfo.y);
				this.mapSprite.draw(this.graphics);
			}
		}
	};
	
	Prototype.draw = function (graphics) {
		this.drawToBuffer();
		this.canvas.draw(graphics);
	};
	
	GameFramework.register(Map);
})();
